﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;
using System.Data.Objects;
using System.Web.Script.Serialization;

namespace Data.Core
{
    /// <summary>
    /// ＥＦ架构——数据上下文统一基类
    /// </summary>
    public abstract class DataBase : IRepository
    {
        /// <summary>
        /// 统一数据上下文对象
        /// </summary>
        protected DbContext EF_DB;

        #region Constructors
        public DataBase(DbContext ef_DB)
            : this(() => { return ef_DB; })
        { }
        public DataBase(Func<DbContext> func)
        {
            this.EF_DB = func();
        }
        #endregion

        #region CURD操作
        #region IRepository 成员
        public virtual IQueryable<TEntity> GetEntities<TEntity>() where TEntity : class
        {
            return EF_DB.Set<TEntity>();
        }

        public virtual void Insert<TEntity>(TEntity entity) where TEntity : class
        {
            EF_DB.Entry<TEntity>(entity);
            EF_DB.Set<TEntity>().Add(entity);
        }

        public virtual void Insert<TEntity>(List<TEntity> entities) where TEntity : class
        {
            entities.ForEach(entity =>
            {
                this.Insert(entity);
            });
        }

        public virtual void Delete<TEntity>(TEntity entity) where TEntity : class
        {
            EF_DB.Set<TEntity>().Attach(entity);
            EF_DB.Set<TEntity>().Remove(entity);
        }

        public virtual void Delete<TEntity>(List<TEntity> entities) where TEntity : class
        {
            entities.ForEach(entity =>
            {
                this.Delete(entity);
            });
        }

        public virtual void Update<TEntity>(TEntity entity) where TEntity : class
        {
            EF_DB.Set<TEntity>().Attach(entity);

        }

        public virtual void Update<TEntity>(List<TEntity> entities) where TEntity : class
        {
            entities.ForEach(entity =>
            {
                this.Update(entity);
            });
        }
        #endregion
        public virtual void SaveChanges()
        {
            try
            {
                EF_DB.SaveChanges();
            }
            catch (System.Data.Entity.Infrastructure.DbUpdateException ex)
            {
                string Message = "error:";
                if (ex.InnerException == null)
                    Message += ex.Message + ",";
                else if (ex.InnerException.InnerException == null)
                    Message += ex.InnerException.Message + ",";
                else if (ex.InnerException.InnerException.InnerException == null)
                    Message += ex.InnerException.InnerException.Message + ",";
                if (ex.Entries != null && ex.Entries.Count() > 0)
                {
                    var _entity = ex.Entries.First();
                    JavaScriptSerializer js = new JavaScriptSerializer();
                    js.Serialize(_entity.Entity);
                    Message += "Status:" + _entity.State + ",";
                    Message += "Entity:" + js.Serialize(_entity.Entity);
                    //XmlSerializer x = new XmlSerializer(_entity.Entity.GetType());
                    //MemoryStream ms = new MemoryStream();
                    //TextWriter writer = new StreamWriter(ms);
                    //x.Serialize(writer, _entity.Entity);
                    //TextReader reader = new StreamReader(ms);
                    //ms.Position = 0;
                    //Message += "Entity:" + reader.ReadToEnd();
                }
                throw new Exception(Message);
            }
        }
        #endregion

    }
}
